package com.tqz.juc.aqs;

import lombok.SneakyThrows;

import java.util.concurrent.locks.ReentrantLock;

/**
 * {@link ReentrantLock} 是独占锁，只能有一个线程访问。
 * 也是可重入锁，也就是一个线程可以加锁多次，注意：加几次锁，就需要解几次锁。
 * 同时它又实现了公平锁和非公平锁。
 *
 * <p>应用场景：抢票、下订单
 *
 * @author tianqingzhao
 * @since 2022/1/23 17:39
 */
public class ReentrantLockTest {

    public static void main(String[] args) {
        System.out.println("main方法开始运行");

        ReentrantLock lock = new ReentrantLock(true);
        int time = 5000;

        new Thread(() -> {
            lock.lock();
            try {
                System.out.println("线程1获取到锁开始执行");
                sleep(time);
            } finally {
                lock.unlock();
                System.out.println("线程1释放锁");
            }
        }, "线程1").start();

        new Thread(() -> {
            lock.lock();
            try {
                System.out.println("线程2获取到锁开始执行");

                sleep(time);
            } finally {
                lock.unlock();
                System.out.println("线程2释放锁");
            }
        }, "线程2").start();

        new Thread(() -> {
            lock.lock();
            try {
                System.out.println("线程3获取到锁开始执行");
                sleep(time);
            } finally {
                lock.unlock();
                System.out.println("线程3释放锁");
            }
        }, "线程3").start();

        System.out.println("main方法结束");

        for (; ; ) {
            sleep(2000);
            System.out.println("===");
        }
    }

    @SneakyThrows
    private static void sleep(int time) {
        Thread.sleep(time);
    }
}
